
<script setup>
/**
 * @name 包含字幕的数字人视频列表
 */
import { onMounted, reactive, ref,createVNode, onUnmounted, computed } from 'vue'
import request from "@/common/utils/request";

import {
  EyeOutlined,
  ExclamationCircleOutlined,
  SaveOutlined,
  EllipsisOutlined,
  DownOutlined
} from "@ant-design/icons-vue";

// 视频文件
import MaterialsModule from "@/views/shotstack/components/MaterialsModule/index.vue";
import { message, Empty, Modal} from 'ant-design-vue';
const materials = ref(null);

const emit = defineEmits(['viewVideo'])

const props = defineProps({
  // id列表
  normalStatusIds: {
    type: Array,
    default: () => []
  } 
})

const state = reactive({
    // 列表数据
    dataSource: [],
  
  // 是否已经挂载
  isInit: false,
  // 日期绑定数据
  time: [],
  // 保存的项
  saveItem: null,
  // 保存到成片库: true; 保存到素材库:false
  isFlaking: false,
  // 保存到素材库的开关
  saveVisible: false,

  // 全选
  checkAll:false,
})

const formState = reactive({
  page: 1,
  pageSize: 20,
  total:0,
  start_time: '',
  end_time: '',
  name:''
})

// 选择的ids
const selectIds = ref([])

// 判断是否是批量保存
const saveListFlage = ref(false)

// 批量上传数组
const filterNotUpdate = ref([])

// 上传的类型
const upload_from = ref('')

// 勾选的视频
const selects = computed(() => {
  const arr = state.dataSource.filter(item => selectIds.value.includes(item.id))
  return arr
})


const statusColor = (status) => {
  switch (status) {
    case 0:
      return "default";
    case 1:
      return "green";
    case 2:
      return "red";
    default:
      return 'default'
  }
};

//查看视频
const toviewVideo = (item) => {
  const url = item?.ai_asr_video_url
  if (url) {
    emit('viewVideo', url)
  }
};

// 保存到剪辑
const importMontage = async() =>{
// const arr = selects.value.filter(ele => ele?.is_save_multimedia != 1)
const arr = JSON.parse(JSON.stringify(selects.value))
if (arr.length) {
  filterNotUpdate.value = arr
  // 保存到素材库
  state.isFlaking = false;
  state.saveVisible = true;
  // 开启批量上传
  saveListFlage.value = true
  upload_from.value = 'backend'
}
}

const importDoneMaterial = () => {
// const arr = selects.value.filter(ele => ele?.is_save_pieces != 1)
const arr = JSON.parse(JSON.stringify(selects.value))
if (arr.length) {
  filterNotUpdate.value = arr
      // 保存到成片
  state.isFlaking = true;
  state.saveVisible = true;
  // 开启批量上传
  saveListFlage.value = true
  upload_from.value = 'shotstack'
  return
}
}

// 下载视频
const handleSave = async (item, type) => {
  state.saveItem = JSON.parse(JSON.stringify(item));
    // 关闭批量上传开关
    saveListFlage.value = false
  if (type == "material") {
    // 保存到素材库
    state.isFlaking = false;
    state.saveVisible = true;
    upload_from.value = 'backend'

  } else if (type == "complete") {
    // 保存到成片
    state.isFlaking = true;
    state.saveVisible = true;
    upload_from.value = 'shotstack'

  } else {
    item.downloading = true;
    // 下载
    const response = await fetch(item.ai_asr_video_url); // 获取视频链接
    const blob = await response.blob(); // 将响应转为 Blob
    const url = window.URL.createObjectURL(blob); // 创建一个 blob URL

    const link = document.createElement("a");
    link.href = url; // 设置 href 为 blob URL
    link.download = "video.mp4"; // 可选，设置下载时的文件名
    document.body.appendChild(link);
    link.click(); // 模拟点击下载
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url); // 清理
    item.downloading = false;
  }
};

// 拿到选择的文件夹等信息
const selfRequest = async (data) => {

  let params

// 批量保存
  if (saveListFlage.value) {
     params = {
      aiAsrData: filterNotUpdate.value.map((item) => {
        return {
            merchant_folder_statck_id: data?.merchant_folder_statck_id,
            ai_asr_id: item?.id,
          upload_from: upload_from.value
        }
      }),
    };
  } else {
     params = {
      aiAsrData: [{
            merchant_folder_statck_id: data?.merchant_folder_statck_id,
            ai_asr_id:  state.saveItem.id,
            upload_from: upload_from.value
       }],
    };
  }

  console.log(params,'批量保存参数');
  
    // 保存到素材 或成片库
    try {
    const res = await request.post(
      "/work_ai",
      "/digital/human/video/moreAddAiAsr",
      params
    );
      if (res?.code && res.code != 1000) throw new Error(res.msg);
      message.success("保存成功");
    } catch (error) {
    message.error(error.message || "保存失败");
  } finally {
      materials.value.stopLoding();
      state.saveVisible = false;
  }

  // console.log(data);
  // const params = {
  //   ai_asr_id: state.saveItem.id,
  //   merchant_folder_statck_id: data?.merchant_folder_statck_id,
  //   // 保存素材库 固定值为backend
  //   upload_from: state.isFlaking ? "" : "backend",
  // };
  // console.log(params, "接口参数");

  // try {
  //   const res = await request.post(
  //     "/work_ai",
  //     "/human/video/media/aiAsr/save",
  //     params
  //   );
  //   if (res?.code && res.code != 1000) throw new Error(res.msg);
  //   console.log(res, "保存成功");
  //   message.success("保存成功");
  // } catch (error) {
  //   message.error(error.message || "保存失败");
  // } finally {
  //     materials.value.stopLoding();
  //     state.saveVisible = false;
  // }
};

// 删除某项视频
const delItem = (data) => {
  Modal.confirm({
    title: "确定要删除该视频吗?",
    icon: createVNode(ExclamationCircleOutlined),
    okText: "确定",
    cancelText: "取消",
    onOk: async () => {
      try {
        const res = await request.del("/work_ai", "/human/video/aiAsr/delete", { id: data.id });
        message.success('删除成功')
        serch();
      } catch (error) {
        // 错误处理
        console.error("删除失败:", error);
      }
    },
  });
};

const resetSerch = () => {
  Object.assign(formState, {
    page: 1,
    pageSize: 20,
    start_time: '',
    end_time: '',
    name:''
  })
  state.time = []
  getList()
}

const serch = () => {
  formState.page = 1
  getList()
}
const timerId = ref(null)
const getList = async () => {

  if (timerId.value) {
    clearTimeout(timerId.value)
    timerId.value = null
  }

  console.log('getList 执行了');
  formState.start_time = state.time?.[0]??''
  formState.end_time = state.time?.[1] ?? ''
  const human_video_ids = props.normalStatusIds?.length? props.normalStatusIds.join(','):''
  const params = {
    page: 1,
    pageSize: 9999,
    human_video_ids
  }

  // 0 - 待执行 1-成功 2-失败
  const res = await request.get(
    "/work_ai",
    "/human/video/aiAsr/list",
    params
  );

  if (Array.isArray(res?.result?.data) && res.result.data.length) {
    const polling = res.result.data.some(ele => ele.status == 0)
    polling && (
      timerId.value = setTimeout(() => {
        getList()
      },4000)
    )
  }
    console.log(res, '列表数据');
  state.dataSource = res?.result?.data ?? []
    formState.total = res?.result.total
}

onMounted(() => {
  state.isInit = true
  getList()
})

// 离开页面, 清除定时器
onUnmounted(() => {
  timerId.value && clearTimeout(timerId.value);
});

const updateList = () => {
  if (state.isInit) {
    getList()
  }
}

// 勾选视频
const selectItem = (item) => {
  // 没有合成成功, 不允许交互
  const index = selectIds.value.findIndex(ele => ele == item?.id)
  if (item?.status != 1) {
    index != -1 && selectIds.value.splice(index, 1)
    return
  }

  if (index == -1) {
    selectIds.value.push(item?.id) 
  } else {
    selectIds.value.splice(index, 1)
  }

  state.checkAll = state.dataSource.length == selectIds.value.length;
};

// 全选
const checkAllChange = () => {
  if (state.checkAll) {
    const arr = state.dataSource.filter(ele => ele.status == 1)
    if(arr.length) {
      selectIds.value = arr.map(ele => ele.id) 
    } else {
      selectIds.value = []
    }
  } else {
    selectIds.value = [] 
  }
};

defineExpose({
  updateList
})

</script>

<template>
    <div class="subtitleCreat">
        <div class="list_conent">

          <div class="title_controls">
          <a-checkbox v-model:checked="state.checkAll" @change="checkAllChange"
            >全选</a-checkbox>
  
          <div class="top_btns">
            <a-dropdown>
            <template #overlay>
              <a-menu :disabled="!selects.length">
                <a-menu-item key="1" @click="importMontage">保存到素材库</a-menu-item>
                <a-menu-item key="2" @click="importDoneMaterial">保存到成片库</a-menu-item>
              </a-menu>
            </template>
            <a-button type="primary" :disabled="!selects.length">
              保存到 <DownOutlined /> 
            </a-button>
          </a-dropdown>
  
          </div>
        </div>


        <!-- 卡片形式的列表 -->
        <div class="cart_list" v-if="state.dataSource.length">
          <div class="cart_item" @click="selectItem(item)" :class="{'select_item': selectIds.includes(item.id)}" v-for="item in state.dataSource" :key="item.id">
            <a-tag class="status_tag" :color="statusColor(item.status)">{{
                item.status_txt
                }}</a-tag>

                <div class="edit_ellip">
                  <a-popover :title="null" placement="bottom">
                    <template #content>
                <div style="display: flex; flex-direction: column;">
                  <!-- :disabled="item.status != 3" -->
                  <a-button type="link"   v-if="item.status == 1"  :loading="item.downloading"
                  @click="handleSave(item, 'down')">下载视频</a-button>
                <!-- <a-button type="link"   v-if="item.isDel == 1" 
                  @click="delItem(item, 'down')">删除视频</a-button> -->
                  </div>
                </template>
                <div class="ellips_box">
                  <EllipsisOutlined v-if="item.status == 1 || item.isDel == 1"></EllipsisOutlined>
                </div>
                </a-popover>
                </div>

            <div class="cart_main">
              <EyeOutlined @click.stop="toviewVideo(item)" class="EyeOutlined"></EyeOutlined>
              <template v-if="item?.asr_log?.data?.cover_url">
                    <img :src="item.asr_log.data.cover_url" alt="" />
              </template>
              <template v-else-if="item?.ai_asr_video_url">
                <video :src="item.ai_asr_video_url"></video>
              </template>
              <template v-else>
                <div class="empty_box">
                  <!-- 暂无封面或视频 -->
                  <a-empty description="暂无封面或视频" :image="Empty.PRESENTED_IMAGE_SIMPLE" style="margin: 0 auto"/>
                </div>
              </template>

              <div class="item_name_box" v-if="item.human_video?.name">
                <span class="item_name">{{ item.human_video.name}}</span>
              </div>
            </div>
            <div class="cart_bottom">
              <div class="msg_box" >

                <a-popover :title="null" placement="top" :getPopupContainer="(target) => {
                  return target.parentNode;
                }">
                  <template #content>
                    <div style="display: flex; flex-direction: column;">
                      <a-button type="link" :disabled="item.status != 1" 
                    @click="handleSave(item, 'material')">保存到素材库</a-button>
                  <a-button type="link" :disabled="item.status != 1" 
                    @click="handleSave(item, 'complete')">保存到成片库</a-button>
                    </div>
                  </template>
                  <a-button type="link" style="padding: 0;" :disabled="item.status != 1">
                    <span style="display: flex; align-items: center; gap:2px; font-weight: bold;">
                      <SaveOutlined style="font-size: 14px;"></SaveOutlined>
                  保存到
                </span>
                  </a-button>
                </a-popover>

              </div>
            </div>
          </div>
        </div>

        <div class="empty_box" style="  " v-else>
          <a-empty :image="Empty.PRESENTED_IMAGE_SIMPLE" style="margin: 0 auto"/>
        </div>

      </div>
    </div>

    <!-- 保存素材文件夹 -->
  <MaterialsModule ref="materials" :requestType="true" jobCategory="videoSplit" :data="state.materialData"
    :material_type="'video'" :isFlaking="state.isFlaking" :visible="state.saveVisible" @selfRequest="selfRequest"
    @onCancel="state.saveVisible = false" />

</template>

<style lang="less" scoped>

.subtitleCreat{
    height: calc(100% - 37px);
    width: 100%;
    // padding-bottom: 100px;
    // padding-top: 20px;



.list_conent{
  height: 100%;

    padding-bottom: 50px;
    display: flex;
    flex-direction: column;

    .empty_box{
      display: flex;
      align-items: center;
      padding: 20px 0;
      flex: 1;
      transform: translateY(25px);
    }

  .serch_title {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      margin-top: 10px;
      margin-bottom: 20px;

      .serch_left {
        display: flex;
        gap: 0 10px;

        .serch_item {
          display: flex;
          justify-content: center;
          align-items: center;

          .left_prefix {
            padding: 0 25px;
            background-color: #ffffff;
            line-height: 30px;
            border: 1px solid #d9d9d9;
            border-right: none;
          }
        }

      }
      }

  // 头部全选等控制按钮
  .title_controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 0;

    .top_btns{
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .title_controls_right {
      display: flex;
      gap: 0 10px;
    }
  }


  .cart_list{
      
      display: flex;
      flex-wrap: wrap;
      align-items: flex-start;
      gap: 20px 20px;
      overflow-y: auto;
      overflow-x: hidden;
      &::-webkit-scrollbar {
            width: 8px; /* 滚动条的宽度 */
            height: 10px; /* 滚动条的高度，垂直滚动条可能用得上 */
        }
        &::-webkit-scrollbar-thumb {
            background: #888; /* 滑块的背景颜色 */
            border-radius: 10px; /* 滑块的圆角 */

        }
      

      .cart_item{
        background-color: #fff;
        position: relative;
        // max-width: 190px;
        border: 2px solid #eee;
        box-shadow: 0 0 12px rgba(0, 0, 0, 0.06); /* 透明度调低更柔和 */
        &.select_item {
          border-color: var(--ss-primary-color);
        }

        .status_tag{
          position: absolute;
          left: 5px;
          top: 5px;
          z-index: 1;
          font-size: 12px;
          font-weight: bold;
        }
        .edit_ellip{
          position: absolute;
          z-index: 3;
          right: 5px;
          top: 5px;
          font-size: 28px;
          color: #fff;
          line-height: 1;
          font-weight: bold;
          cursor: pointer;
          .ellips_box{
            background: #0000004b;
            padding: 0 5px;
            border-radius: 8px;
          }
        }
        .cart_main{
          height: 280px;
          width: 190px;
          cursor: pointer;
          position: relative;
          overflow: hidden;

                  // name 遮罩层
        .item_name_box{
          position: absolute;
          bottom: 0;
          left: 0;
          width: 100%;
          padding: 2px 5px;
          background: #0000004b;
          .item_name{
              color: #fff;
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-line-clamp: 1;
              -webkit-box-orient: vertical;
              width: auto;
            }
        }

          img{
            height: 100%;
            width: 100%;
            object-fit: cover;
          }
          video{
            height: auto;
            width: 100%;
          }
          .empty_box{
            height: 100%;
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            // background-color: #00000017;
          }

          &::after{
          content: '';
          position: absolute;
          left: 0;
          top: 0;
          z-index: 2;
          background-color: transparent;
          opacity: 0;
          transition: all .3s;
          height: 100%;
          width: 100%;
        }
          &:hover{
          &::after{
            background-color: #00000056;
            opacity: 1;
          }

          .EyeOutlined{
            opacity: 1;
          }
        }

        .EyeOutlined{
          position: absolute;
          z-index: 3;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          color: #fff;
          transition: all .3s;
          opacity: 0;
          font-size: 30px;
          &:hover{
            color: var(--ss-primary-color-hover);
          }
        }
        }
        .cart_bottom{
          width: 100%;
          background-color: #fff;
          padding: 5px 5px;
          font-weight: bold;
          border-top: 1px solid #eee;

          .msg_box{
            display: flex;
            justify-content: space-between;
            align-items: center;


          }
        }
      }
    }
}

    // 分页
  .smart_clip_content_pagination {
    display: flex;
    margin-top: 20px;
    justify-content: flex-end;
  }
}
</style>